/**************************************************************************************
*
*	Copyright (C) 2010 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	GraphicsResourceManager.cpp
*
*	Comments	-	See GraphicsResourceManager.h
*
**************************************************************************************/

#ifdef __PSX_WINDOWS_WINDOW

#include "../Include/GraphicsResourceManager.h"
#include "../Include/GraphicsTypes.h"

namespace Pulse
{

	GraphicsResourceManager::GraphicsResourceManager( void )
	{

	}

	GraphicsResourceManager::~GraphicsResourceManager( void )
	{

	}

	Buffer * GraphicsResourceManager::CreateBuffer( BufferDesc *pDesc )
	{
		return m_buffers.Create( pDesc );
	}
	
	Buffer * GraphicsResourceManager::CreateBuffer( const CHAR *pName, BufferDesc *pDesc )
	{
		return m_buffers.Create( pName, pDesc );
	}

	StructuredBuffer * GraphicsResourceManager::CreateStructuredBuffer( StructuredBufferDesc *pDesc )
	{
		return m_structuredBuffers.Create( pDesc );
	}

	StructuredBuffer * GraphicsResourceManager::CreateStructuredBuffer( const CHAR *pName, StructuredBufferDesc *pDesc )
	{
		return m_structuredBuffers.Create( pName, pDesc );
	}
		
	VertexBuffer * GraphicsResourceManager::CreateVertexBuffer( VertexBufferDesc *pDesc )
	{
		return m_vertexBuffers.Create( pDesc );
	}

	VertexBuffer * GraphicsResourceManager::CreateVertexBuffer( const CHAR *pName, VertexBufferDesc *pDesc )
	{
		return m_vertexBuffers.Create( pName, pDesc );
	}

	IndexBuffer * GraphicsResourceManager::CreateIndexBuffer( IndexBufferDesc *pDesc )
	{
		return m_indexBuffers.Create( pDesc );
	}

	IndexBuffer * GraphicsResourceManager::CreateIndexBuffer( const CHAR *pName, IndexBufferDesc *pDesc )
	{
		return m_indexBuffers.Create( pName, pDesc );
	}

	Texture2D * GraphicsResourceManager::CreateTexture2D( Texture2DDesc *pDesc )
	{
		return m_2DTextures.Create( pDesc );
	}

	Texture2D * GraphicsResourceManager::CreateTexture2D( const CHAR *pName, Texture2DDesc *pDesc )
	{
		Texture2D *pTex = m_2DTextures.Create( pName, pDesc );

		return pTex;
	}

	SwapChain * GraphicsResourceManager::CreateSwapChain( SwapChainDesc *pDesc )
	{
		return m_swapChains.Create( pDesc );
	}

	SwapChain * GraphicsResourceManager::CreateSwapChain( const CHAR *pName, SwapChainDesc *pDesc )
	{
		return m_swapChains.Create( pName, pDesc );
	}

	DepthStencilState * GraphicsResourceManager::CreateDepthStencilState( DepthStencilStateDesc *pDesc )
	{
		return m_depthStencilStates.Create( pDesc );
	}
	
	DepthStencilState * GraphicsResourceManager::CreateDepthStencilState( const CHAR *pName, DepthStencilStateDesc *pDesc )
	{
		return m_depthStencilStates.Create( pName, pDesc );
	}

	BlendState * GraphicsResourceManager::CreateBlendState( BlendStateDesc *pDesc )
	{
		return m_blendStates.Create( pDesc );
	}
	
	BlendState * GraphicsResourceManager::CreateBlendState( const CHAR *pName, BlendStateDesc *pDesc )
	{
		return m_blendStates.Create( pName, pDesc );
	}

	RasterizerState * GraphicsResourceManager::CreateRasterizerState( RasterizerStateDesc *pDesc )
	{
		return m_rasterizerStates.Create( pDesc );
	}
	
	RasterizerState * GraphicsResourceManager::CreateRasterizerState( const CHAR *pName, RasterizerStateDesc *pDesc )
	{
		return m_rasterizerStates.Create( pName, pDesc );
	}

	ConstantBuffer * GraphicsResourceManager::CreateConstantBuffer( ConstantBufferDesc *pDesc )
	{
		return m_constantBuffers.Create( pDesc );
	}
	
	ConstantBuffer * GraphicsResourceManager::CreateConstantBuffer( const CHAR *pName, ConstantBufferDesc *pDesc )
	{
		return m_constantBuffers.Create( pName, pDesc );
	}

	VertexShader * GraphicsResourceManager::CreateVertexShader( ShaderDesc *pDesc )
	{
		return m_vertexShaders.Create( pDesc );
	}

	VertexShader * GraphicsResourceManager::CreateVertexShader( const CHAR *pName, ShaderDesc *pDesc )
	{
		return m_vertexShaders.Create( pName, pDesc );
	}

	HullShader * GraphicsResourceManager::CreateHullShader( ShaderDesc *pDesc )
	{
		return m_hullShaders.Create( pDesc );
	}

	HullShader * GraphicsResourceManager::CreateHullShader( const CHAR *pName, ShaderDesc *pDesc )
	{
		return m_hullShaders.Create( pName, pDesc );
	}

	DomainShader * GraphicsResourceManager::CreateDomainShader( ShaderDesc *pDesc )
	{
		return m_domainShaders.Create( pDesc );
	}

	DomainShader * GraphicsResourceManager::CreateDomainShader( const CHAR *pName, ShaderDesc *pDesc )
	{
		return m_domainShaders.Create( pName, pDesc );
	}

	GeometryShader * GraphicsResourceManager::CreateGeometryShader( ShaderDesc *pDesc )
	{
		return m_geometryShaders.Create( pDesc );
	}

	GeometryShader * GraphicsResourceManager::CreateGeometryShader( const CHAR *pName, ShaderDesc *pDesc )
	{
		return m_geometryShaders.Create( pName, pDesc );
	}

	PixelShader * GraphicsResourceManager::CreatePixelShader( ShaderDesc *pDesc )
	{
		return m_pixelShaders.Create( pDesc );
	}

	PixelShader * GraphicsResourceManager::CreatePixelShader( const CHAR *pName, ShaderDesc *pDesc )
	{
		return m_pixelShaders.Create( pName, pDesc );
	}

	ComputeShader * GraphicsResourceManager::CreateComputeShader( ShaderDesc *pDesc )
	{
		return m_computeShaders.Create( pDesc );
	}

	ComputeShader * GraphicsResourceManager::CreateComputeShader( const CHAR *pName, ShaderDesc *pDesc )
	{
		return m_computeShaders.Create( pName, pDesc );
	}

	InputLayout * GraphicsResourceManager::CreateInputLayout( InputLayoutDesc *pDesc )
	{
		return m_inputLayouts.Create( pDesc );
	}

	InputLayout * GraphicsResourceManager::CreateInputLayout( const CHAR *pName, InputLayoutDesc *pDesc )
	{
		return m_inputLayouts.Create( pName, pDesc );
	}

	Geometry * GraphicsResourceManager::CreateGeometry( GeometryDesc *pDesc )
	{
		return m_geometries.Create( pDesc );
	}

	Geometry * GraphicsResourceManager::CreateGeometry( const CHAR *pName, GeometryDesc *pDesc )
	{
		return m_geometries.Create( pName, pDesc );
	}

	Material * GraphicsResourceManager::CreateMaterial( MaterialDesc *pDesc )
	{
		return m_materials.Create( pDesc );
	}
	
	Material * GraphicsResourceManager::CreateMaterial( const CHAR *pName, MaterialDesc *pDesc )
	{
		return m_materials.Create( pName, pDesc );
	}

	RenderTechnique * GraphicsResourceManager::CreateRenderTechnique( RenderTechniqueDesc *pDesc )
	{
		return m_techniques.Create( pDesc );
	}
	
	RenderTechnique * GraphicsResourceManager::CreateRenderTechnique( const CHAR *pName, RenderTechniqueDesc *pDesc )
	{
		return m_techniques.Create( pName, pDesc );
	}

	Effect * GraphicsResourceManager::CreateEffect( EffectDesc *pDesc )
	{
		return m_effects.Create( pDesc );
	}
	
	Effect * GraphicsResourceManager::CreateEffect( const CHAR *pName, EffectDesc *pDesc )
	{
		return m_effects.Create( pName, pDesc );
	}

	Effect * GraphicsResourceManager::FindEffect( const CHAR *pName )
	{
		return m_effects.Find( pName );
	}

	Model * GraphicsResourceManager::CreateModel( ModelDesc *pDesc )
	{
		return m_models.Create( pDesc );
	}
	
	Model * GraphicsResourceManager::CreateModel( const CHAR *pName, ModelDesc *pDesc )
	{
		return m_models.Create( pName, pDesc );
	}

	EErrorCode::Type GraphicsResourceManager::Initialize( void )
	{
		// TODO: We can transfer the growSize to a script to make it dynamic.
		//ResourceManager *pResMan = ResourceManager::GetInstance();

		// Initialize and register sub-resource-managers
		m_buffers.Initialize( 5, ResourceCode( EResource::VIDEO, EVideoResource::BUFFER ) );
		m_structuredBuffers.Initialize( 5, ResourceCode( EResource::VIDEO, EVideoResource::STRUCTURED_BUFFER ) );
		m_vertexBuffers.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::VERTEX_BUFFER ) );
		m_indexBuffers.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::INDEX_BUFFER ) );
		/*m_2Dtextures.Create( 20 );
		pResMan->RegisterResourcePool( &m_2Dtextures, ResourceCode( EResource::VIDEO, EVideoResource::TEXTURE2D ) );*/
		m_2DTextures.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::TEXTURE2D ) );
		/*m_swapChains.Create( 5 );
		pResMan->RegisterResourcePool( &m_swapChains, ResourceCode( EResource::VIDEO, EVideoResource::SWAP_CHAIN ) );*/
		m_swapChains.Initialize(5, ResourceCode( EResource::VIDEO, EVideoResource::SWAP_CHAIN ) );
		m_depthStencilStates.Initialize( 10, ResourceCode( EResource::VIDEO, EVideoResource::DEPTH_STENCIL_STATE ) );
		m_blendStates.Initialize( 10, ResourceCode( EResource::VIDEO, EVideoResource::BLEND_STATE ) );
		m_rasterizerStates.Initialize( 10, ResourceCode( EResource::VIDEO, EVideoResource::RASTERIZER_STATE ) );
		m_constantBuffers.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::CONSTANT_BUFFER ) );
		/*m_vertexShaders.Create( 20 );
		pResMan->RegisterResourcePool( &m_vertexShaders, ResourceCode( EResource::VIDEO, EVideoResource::VERTEX_SHADER ) );*/
		m_vertexShaders.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::SHADER ) );
		/*m_hullShaders.Create( 20 );
		pResMan->RegisterResourcePool( &m_hullShaders, ResourceCode( EResource::VIDEO, EVideoResource::HULL_SHADER ) );*/
		m_hullShaders.Initialize( 20, ResourceCode( EResource::VIDEO, EVideoResource::SHADER ) );
		/*m_domainShaders.Create( 20 );
		pResMan->RegisterResourcePool( &m_domainShaders, ResourceCode( EResource::VIDEO, EVideoResource::DOMAIN_SHADER ) );*/
		m_domainShaders.Initialize( 20, ResourceCode( EResource::VIDEO, EVideoResource::SHADER ) );
		/*m_geometryShaders.Create( 20 );
		pResMan->RegisterResourcePool( &m_geometryShaders, ResourceCode( EResource::VIDEO, EVideoResource::GEOMETRY_SHADER ) );*/
		m_geometryShaders.Initialize( 20, ResourceCode( EResource::VIDEO, EVideoResource::SHADER ) );
		/*m_pixelShaders.Create( 20 );
		pResMan->RegisterResourcePool( &m_pixelShaders, ResourceCode( EResource::VIDEO, EVideoResource::PIXEL_SHADER ) );*/
		m_pixelShaders.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::SHADER ) );
		/*m_computeShaders.Create( 20 );
		pResMan->RegisterResourcePool( &m_computeShaders, ResourceCode( EResource::VIDEO, EVideoResource::COMPUTE_SHADER ) );*/
		m_computeShaders.Initialize( 20, ResourceCode( EResource::VIDEO, EVideoResource::SHADER ) );
		/*m_inputLayouts.Create( 20 );
		pResMan->RegisterResourcePool( &m_inputLayouts, ResourceCode( EResource::VIDEO, EVideoResource::INPUT_LAYOUT ) );*/
		m_inputLayouts.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::INPUT_LAYOUT ) );
		m_geometries.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::GEOMETRY ) );
		m_materials.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::GEOMETRY ) );
		m_techniques.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::TECHNIQUE ) );
		m_effects.Initialize( 100, ResourceCode( EResource::VIDEO, EVideoResource::TECHNIQUE ) );
		m_models.Initialize( 100, ResourceCode( EResource::VIDEO, EWorldResource::MODEL ) );

		return EErrorCode::OKAY;
	}

	void GraphicsResourceManager::Cleanup( void )
	{
		/*ResourceManager *pResMan = ResourceManager::GetInstance();
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::SWAP_CHAIN ) );
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::TEXTURE2D ) );
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::VERTEX_BUFFER) );
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::HULL_SHADER ) );
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::DOMAIN_SHADER ) );
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::GEOMETRY_SHADER ) );
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::PIXEL_SHADER ) );
		pResMan->UnregisterResourcePool( ResourceCode( EResource::VIDEO, EVideoResource::COMPUTE_SHADER ) );*/

		m_models.Cleanup();
		m_effects.Cleanup();
		m_techniques.Cleanup();
		m_materials.Cleanup();
		m_geometries.Cleanup();
		m_computeShaders.Cleanup();
		m_pixelShaders.Cleanup();
		m_geometryShaders.Cleanup();
		m_domainShaders.Cleanup();
		m_hullShaders.Cleanup();
		m_vertexShaders.Cleanup();
		m_constantBuffers.Cleanup();
		m_depthStencilStates.Cleanup();
		m_swapChains.Cleanup();
		m_2DTextures.Cleanup();
		m_indexBuffers.Cleanup();
		m_vertexBuffers.Cleanup();
		m_structuredBuffers.Cleanup();
		m_buffers.Cleanup();

	}

	
}

#endif __PSX_WINDOWS_WINDOW
